package Controllers;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Observable;
import java.util.Observer;
import Entities.RegisterClientEntity;
import GUI.RegisterClientGUI;
import Server.RsWraper;
import Server.Tuple;

/**
 * RegisterClientController class implements Validate and Observer interface.
 * this class registers new clients into the database.
 * @author Ofek-az
 *
 */
public class RegisterClientController implements Validate,Observer{
	/**
	 * This is the registerClient boundary.
	 */
	private RegisterClientGUI registerClientGui;
	/**
	 * This is the registerClient entity.
	 */
	private RegisterClientEntity registerClientEnt;
	/**
	 * This is the previous window (login window).
	 */
	private CustomerRelationsController prev;
	
	/** The operation. */
	private int operation=0;
	
	/** The tuples. */
	private ArrayList<Tuple> tuples;
	
	/**
	 * This is the constructor.
	 *
	 * @param registerClientGui the register client gui
	 * @param registerClientEnt the register client entity
	 */
	public RegisterClientController(RegisterClientGUI registerClientGui,RegisterClientEntity registerClientEnt) {
		this.registerClientGui = registerClientGui;
		this.registerClientEnt = registerClientEnt;
		ClientController.setObserver(this);
		this.registerClientGui.addRegisterActionListener(new RegisterListener() );
		this.registerClientGui.addBackActionListener(new BackListener());
		addLivingAreasToCb();
		this.registerClientGui.setVisible(true);
	}
	
	/**
	 * Adds the living areas to cb.
	 */
	private void addLivingAreasToCb()
	{
		String query = "SELECT livingareas.name FROM livingareas";
		try {
			ClientController.observableClient.sendToServer(query);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
	}
	/**
	* RegisterListener class implements ActionListener interface.
	* this class controls the register button.
	 * @author Ofek-az
	 *
	 */
	class RegisterListener implements ActionListener
	{

		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			if(validateInput())
			{
				registerClientEnt.setUid(registerClientGui.getUidTf().getText());
				registerClientEnt.setPass(registerClientGui.getPassTf().getText());
				registerClientEnt.setName(registerClientGui.getNameTf().getText());
				registerClientEnt.setEmail(registerClientGui.getEmailTf().getText());
				int birthyear=Integer.valueOf((String) registerClientGui.getDobTf().getText().subSequence(6,10));
				int currentyear=Integer.valueOf((new Date()).getYear())+1900;
				registerClientEnt.setAge(currentyear-birthyear);
				registerClientEnt.setPhoneNumber(registerClientGui.getPhoneTf().getText());
				registerClientEnt.setLivingArea((String) registerClientGui.getLaCb().getSelectedItem());
	
				String regQuery="INSERT INTO customers (`cid`,`importancerank`) VALUES ('"+registerClientEnt.getCid()+"','1')";	//register new customer (in customers table) query.
				
				try {
					ClientController.observableClient.sendToServer(regQuery);
					
					
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				
				
			}
			
		}
		
	}
	/**
	* BackListener class implements ActionListener interface.
	* this class controls the back button.
	 * @author Ofek-az
	 *
	 */
	class BackListener implements ActionListener
	{

		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			LoginController.mainWindow.setContentPane(prev.getCustomerRelationsGUI());
		}

	}
	
	/* (non-Javadoc)
	 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
	 */
	@Override
	public void update(Observable arg0, Object arg) {
		String msg = (String) arg.toString();
		if(msg.equals("error"))
			registerClientGui.displayWarningMessage("The same customer is already exists");
		else
			if(operation==0)
			{
				tuples=new ArrayList<Tuple>();
				Tuple tuple=new Tuple();
				tuple.put("NAME"," ");		//puts a blank option in the first cell
				tuples.add(tuple);
				tuples.addAll(((RsWraper)arg).getRows());		//appends all products list
				for(int i=0;i<tuples.size();i++)
				{
					registerClientGui.getLaCb().addItem(tuples.get(i).get("NAME"));
				}
				
				operation=1;
			}
			else if(operation==1)
			{
				String regQuery="INSERT INTO users (`uid`, `password`, `name`, `livingArea`, `age`, `phoneNumber`, `email`, `loginStatus`) VALUES ('"+registerClientEnt.getCid()+"', '"+registerClientEnt.getPass()+"', '"+registerClientEnt.getName()+"', '"+registerClientEnt.getLivingArea()+"','"+registerClientEnt.getAge()+"', '"+registerClientEnt.getPhoneNumber()+"', '"+registerClientEnt.getEmail()+"', '0')";	//register new customer(in users table) query.
				try {
					ClientController.observableClient.sendToServer(regQuery);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				operation=2;
			}
			else{
			registerClientGui.displayMessage("Register succeded");
			operation=1;
			}
	}
	/*
	 * (non-Javadoc)
	 * 
	 * @see Controllers.Validate#validateInput()
	 */
	@Override
	public boolean validateInput() {
		String id=registerClientGui.getUidTf().getText();
		String pass=registerClientGui.getPassTf().getText();
		String name=registerClientGui.getNameTf().getText();
		String email=registerClientGui.getEmailTf().getText();
		String dob=registerClientGui.getDobTf().getText();
		String phoneNumber=registerClientGui.getPhoneTf().getText();
		String livingarea=(String) registerClientGui.getLaCb().getSelectedItem();
		if(id.equals("")||pass.equals("")||name.equals("")||email.equals("")||dob.equals("")||phoneNumber.equals("")||livingarea.equals(" "))
		{
			registerClientGui.displayWarningMessage("Please fill all the missing fields.");
			return false;
		}
		else
		{
			try
			{
				Integer.parseInt(id);
			}
			catch (NumberFormatException e)
			{
				registerClientGui.displayWarningMessage("Error:illeagel characters in id field.");
				return false;
			}
			try
			{
				Integer.parseInt(phoneNumber);
			}
			catch (NumberFormatException e)
			{
				registerClientGui.displayWarningMessage("Error:illeagel characters in phone number field.");
				return false;
			}
			if(!isValidDate(registerClientGui.getDobTf().getText()))
			{
				registerClientGui.displayWarningMessage("Error:illeagel date entered");
				return false;
			}
			return true;
		}
	}

	/**
	 * Sets the previous controller.
	 *
	 * @param prev the new previous controller
	 */
	public void setPrev(CustomerRelationsController prev) {
		this.prev = prev;
	}
	
	/**
	 * Checks if is valid date.
	 *
	 * @param date the date
	 * @return true, if is valid date
	 */
	public boolean isValidDate(String date)
	{
		GregorianCalendar cal = new GregorianCalendar();
		cal.setLenient(false);
		cal.set(Calendar.DAY_OF_MONTH,Integer.parseInt(date.substring(0,2)));
		cal.set(Calendar.MONTH, Integer.parseInt(date.substring(3,5)));
		cal.set(Calendar.YEAR, Integer.parseInt(date.substring(6,10)));
		try{
		System.out.println(cal.get(Calendar.DAY_OF_MONTH)+"/"+cal.get(Calendar.MONTH)+"/"+cal.get(Calendar.YEAR));
		if(cal.get(Calendar.DAY_OF_MONTH)>0&&cal.get(Calendar.DAY_OF_MONTH)<32)
			if(cal.get(Calendar.MONTH)>0&&cal.get(Calendar.MONTH)<13)
				if(cal.get(Calendar.YEAR)>0&&cal.get(Calendar.YEAR)<=(Integer.valueOf((new Date()).getYear())+1900))
					return true;
		return false; 
		}
		catch(IllegalArgumentException e)
		{
			return false;
		}
	}
	
}
